#pragma once
#include <iostream>
#include <string>
#include <mutex>
#include "../util/util.hpp"
namespace db
{
    using namespace ns_log;
    const int BUFF_SIZE = 4096;
    class UserInfo
    {
    private:
        util::MySQLTool _mysql;
        std::mutex _mtx;

    public:
        UserInfo(const std::string &host,
                 const std::string &user,
                 const std::string &password,
                 const std::string &database,
                 unsigned int port = 3306,
                 const char *unix_socket = nullptr,
                 unsigned int clientflag = 0)
        {
            _mysql.Connect(host, user, password, database, port, unix_socket, clientflag);
        }
        ~UserInfo()
        {}
        // 新增用户
        void Insert(Json::Value &user)
        {
            #define INSERT R"( insert into user values (null,'%s',SHA2('%s',256),1000,0,0); )"
            std::string username = user["username"].asString();
            std::string password = user["password"].asString();
            char buff[BUFF_SIZE];
            sprintf(buff, INSERT, username.c_str(), password.c_str());
            _mysql.Query(buff);
        }
        // 登录，并且返回用户详细信息
        bool Login(Json::Value &user)
        {
            #define LOGIN_USER R"( select id,score,total_cnt,win_cnt from user where username='%s' and password=SHA2('%s',256);)"
            std::string username = user["username"].asString();
            std::string password = user["password"].asString();
            char buff[BUFF_SIZE];
            sprintf(buff, LOGIN_USER, username.c_str(), password.c_str());
            std::vector<MYSQL_ROW> res;
            int filed = 0;
            _mysql.Query(buff,&res,&filed);
            if(res.size() != 1)
            {
                LOG(DEBUG,"没有查询到用户:%s的信息,或者账号/密码错误\n",username.c_str());
                return false;
            }
            user["id"] = std::stoi(res[0][0]);
            user["score"] = std::stoi(res[0][1]);
            user["total_cnt"] = std::stoi(res[0][2]);
            user["win_cnt"] = std::stoi(res[0][3]);
            return true;
        }
        // 查找用户
        bool FindUser(int id, Json::Value &user)
        {
            #define SELECT_USER_BY_ID R"(select username,score,total_cnt,win_cnt from user where id = %d;)"
            char buff[BUFF_SIZE];
            sprintf(buff, SELECT_USER_BY_ID, id);
            std::vector<MYSQL_ROW> res;
            int filid = 0;

            {
                std::lock_guard<std::mutex> lock(_mtx);
                _mysql.Query(buff,&res,&filid);
            }

            if(res.size() != 1)
            {
                LOG(DEBUG,"没有查询到用户id = %d的信息\n",id);
                return false;
            }
            user["username"] = res[0][0];
            user["score"] = std::stoi(res[0][1]);
            user["total_cnt"] = std::stoi(res[0][2]);
            user["win_cnt"] = std::stoi(res[0][3]);
            return true;
        }
        bool FindUser(const std::string &name, Json::Value &user)
        {
            #define SELECT_USER_BY_NAME R"(select id,score,total_cnt,win_cnt from user where username = '%s';)"
            char buff[BUFF_SIZE];
            sprintf(buff, SELECT_USER_BY_NAME, name.c_str());
            std::vector<MYSQL_ROW> res;
            int filid = 0;
            {
                std::lock_guard<std::mutex> lock(_mtx);
                _mysql.Query(buff,&res,&filid);
            }
            if(res.size() != 1)
            {
                LOG(DEBUG,"没有查询到用户%s的信息\n",name.c_str());
                return false;
            }
            user["id"] = res[0][0];
            user["score"] = std::stoi(res[0][1]);
            user["total_cnt"] = std::stoi(res[0][2]);
            user["win_cnt"] = std::stoi(res[0][3]);
            return true;
        }
        // 增加天梯积分
        void AddScoreAndCnt(int id,int score)
        {
            #define ADD_SCORE R"(update user set score = score + %d,total_cnt = total_cnt + 1,win_cnt = win_cnt + 1 where id = %d ;)"
            char buff[BUFF_SIZE];
            sprintf(buff, ADD_SCORE, score,id);
            _mysql.Query(buff);
        }
        // 减少天梯积分
        void ReduceScore(int id,int score)
        {
            #define DEL_SCORE R"(update user set score = score - %d,total_cnt = total_cnt + 1 where id = %d ;)"
            char buff[BUFF_SIZE];
            sprintf(buff, DEL_SCORE, score,id);
            _mysql.Query(buff);
        }
    };
}